package core;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import persistence.DataPersistor;

import core.exception.IllegalAddException;
import core.exception.SaveException;

public class SerializablePersistenceTest {
	
	static ISaver saver;
	static ILoader loader;
	static File file;
	static Product testP;
	
	
	static ContainerFacade cFacade;
	static ItemFacade iFacade;
	static ProductFacade pFacade;
	
	static RootStorageUnit cManager;
	static ItemManager iManager;
	static ProductManager pManager;
	

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		DataPersistor.instance().init("-serial");
		ContainerFacade.clearAllData();
		ItemFacade.clearAllData();
		ProductFacade.clearAllData();
		saver = new SerializableSaver();
		loader = new SerializableLoader();
		file = new File("tracker.tkr");
		cFacade = ContainerFacade.instance();
		iFacade = ItemFacade.instance();
		pFacade = ProductFacade.instance();
		
		cManager = RootStorageUnit.instance();
		iManager = ItemManager.instance();
		pManager = ProductManager.instance();
		
		testP = new Product(new Barcode("512345123459", BarcodeType.PRODUCT),
				"A test Product.",
				new Amount(3.59F, UnitOfMeasurement.kilograms),
				6, 9);
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		loader.close();
		saver = null;
		loader = null;
		file.delete();
	}

	@Before
	public void setUp() throws Exception {
		//trackerInstance = Tracker.instance();
	}

	@After
	public void tearDown() throws Exception {
		//trackerInstance = null;
	}

	@Test
	public void testLoadAndSave() {
		
		//add a container
		Container testSU = null;
		Item testI = null;
		try {
			testSU = cFacade.addStorageUnit("TestSU");
		} catch (IllegalAddException | SaveException e) {
			e.printStackTrace();
			fail("IllegalAddException");
		}
		assertTrue(testSU != null);
		assertTrue(cManager.containsContainer(testSU));
		
		//add a product
		try {
			pFacade.createProduct(testP, testSU);
		} catch (IllegalAddException e) {
			e.printStackTrace();
			fail("IllegalAddException");
		}
		assertTrue(pManager.containsProduct(testP.getBarcode()));
		
		//add an item
		try {
			testI = iFacade.addItem(testP, testSU);
		} catch (IllegalAddException e) {
			e.printStackTrace();
			fail("IllegalAddException");
		} catch (SaveException e){
			e.printStackTrace();
			fail("SaveException");
		}
		assertTrue(testI != null);
		assertTrue(iManager.lookupByBarcode(testI.getBarcode()) != null);
		
		//save to a file
		try {
			saver.save();
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException");
		}
		
		//load from the file
		try {
			loader.load();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			fail("ClassNotFoundException");
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException");
		}		
		
		//make sure the stuff added is still there.
		assertTrue(RootStorageUnit.instance().containsContainer(testSU));
		assertTrue(ProductManager.instance().containsProduct(testP.getBarcode()));
		assertTrue(ItemManager.instance().lookupByBarcode(testI.getBarcode()) != null);
		
	}

}
